import CryptoJS from 'crypto-js'

export interface IUseCrypto {
    encrypt: (message: string, cryptoKey?: string, options?: IEncryptOptions) => string
    decrypt: (encryptedMessage: string, cryptoKey?: string, options?: IEncryptOptions) => string
}

export interface IEncryptOptions {
    keySize?: number
    ivSize?: number
    iterationCount?: number
    salt?: string | CryptoJS.lib.WordArray
}

export const useCrypto = (): IUseCrypto => {
    // 定义默认的加密选项
    const defaultOptions: IEncryptOptions = {
        keySize: 128 / 32,
        ivSize: 128 / 32,
        iterationCount: 1000,
        salt: 'salt',
    }

    return {
        encrypt: (message, cryptoKey = 'hyl', options = {}) => {
            options = Object.assign(defaultOptions, options);
            // 获取加密选项
            const { keySize, ivSize, iterationCount, salt }: IEncryptOptions = { ...CryptoJS.defaultOptions, ...options };
            // 将 salt 转换为 WordArray 类型
            const stalVal = typeof salt === 'string' ? CryptoJS.enc.Utf8.parse(salt) : salt;
            // 使用 PBKDF2 算法生成密钥
            const PBKDF2key = CryptoJS.PBKDF2(cryptoKey, stalVal, {
                keySize,
                iterations: iterationCount
            })
            // 生成随机的 IV
            const iv = CryptoJS.lib.WordArray.random(ivSize * 4)
            // 使用 AES 算法对字符串进行加密
            const encrypted = CryptoJS.AES.encrypt(message, PBKDF2key, { iv })
            // 返回加密结果
            return `${CryptoJS.enc.Base64.stringify(iv)}:${encrypted}`
        },
        decrypt: (encryptedMessage, cryptoKey = 'hyl', options = {}) => {
            options = Object.assign(defaultOptions, options);
            // 获取加密选项
            const { keySize, ivSize, iterationCount, salt }: IEncryptOptions = {
                ...CryptoJS.defaultOptions,
                ...options,
            };

            // 将 salt 转换为 WordArray 类型
            const saltValue = typeof salt === 'string' ? CryptoJS.enc.Utf8.parse(salt) : salt;

            // 将加密结果拆分为 IV 和加密字符串
            const [ivBase64, encrypted] = encryptedMessage.split(':');

            // 将 IV 转换为 WordArray 类型
            const iv = CryptoJS.enc.Base64.parse(ivBase64);

            // 使用 PBKDF2 算法生成密钥
            const PBKDF2key = CryptoJS.PBKDF2(cryptoKey, saltValue, {
                keySize,
                iterations: iterationCount,
            });

            // 使用 AES 算法对加密字符串进行解密
            const decrypted = CryptoJS.AES.decrypt(encrypted, PBKDF2key, { iv });

            // 返回解密结果
            return decrypted.toString(CryptoJS.enc.Utf8);
        }
    }
}